package cn.kimming.rpc.remoting.registry;

import cn.kimming.rpc.common.exception.RpcException;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;

public class ClientRpcRegistry {
    private static final Logger logger = LoggerFactory.getLogger(ClientRpcRegistry.class);
    private static ConcurrentHashMap<String, CuratorFramework> clientMap = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, ServiceDiscovery> discoveryMap = new ConcurrentHashMap<>();

    /**
     * 服务端的zk连接,
     */
    private static CuratorFramework serverClient;
    private static ServiceDiscovery<InstanceDetail> serviceDiscovery;

    public static CuratorFramework getClient(String registryUrl) throws RpcException{
        try {
            CuratorFramework client = clientMap.computeIfAbsent(registryUrl, (key) -> {
                CuratorFramework newClient = CuratorFrameworkFactory.newClient(registryUrl,
                        new ExponentialBackoffRetry(RegistryConstants.DEFAULT_BASE_SLEEP_TIME_MS,
                                RegistryConstants.DEFAULT_MAX_RETRIES));
                newClient.start();
                return newClient;
            });
            return client;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RpcException("获取zk连接: " + registryUrl + " 失败");
        }
    }

    public static ServiceDiscovery<InstanceDetail> getDiscovery(String registryUrl) {
        CuratorFramework client = getClient(registryUrl);

        ServiceDiscovery discovery = discoveryMap.computeIfAbsent(registryUrl, (key) -> {
            ServiceDiscovery newDiscovery = ServiceDiscoveryBuilder.builder(InstanceDetail.class)
                    .basePath(RegistryConstants.BASE_PATH)
                    .client(client)
                    .build();
            try {
                newDiscovery.start();
            } catch (Exception e) {
                logger.error("[my-rpc] curator discovery init error", e);
            }
            return newDiscovery;
        });
        return discovery;
    }


}
